# coding=utf-8
import os
import sys
import time
import re
import logging
import base64
from bid.ai_generate.get_team import get_team

t = time.time()
import requests
import json
import logging
from datetime import datetime
# from zentao.settings import PYMYSQL_CONF, DIFY_URL
DIFY_URL = 'http://127.0.0.1:8083'
PYMYSQL_CONF = {
    'host': '127.0.0.1',
    # 'host': '172.16.159.132',
    'password': '123456',
    # 'password': 'Sqdmm123#',
    'port': 3306,  # MySQL服务端口
    'user': 'root',
    'database': 'zentao',
    'charset': 'utf8mb4'
}

current_time = datetime.now()

import os

# 设置日志
ptah = "./out_log/"
if not os.path.exists(ptah):
    os.mkdir(ptah)

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s',
                    filename='./out_log/' + current_time.strftime("%Y-%m-%d_%H-%M-%S") + 'dawate_log.txt',
                    filemode='a')  # 追加模式


def dify_chat2(query, conversation_id=''):
    # API端点和API密钥
    # url = 'http://172.16.32.45:11206/v1/chat-messages' #v1/chat-messages'调用聊天框  workflows/run智能体
    # url = 'http://192.168.41.:8083/v1/chat-messages'  # v1/chat-messages'调用聊天框  workflows/run智能体
    url = f'{DIFY_URL}/v1/chat-messages'  # v1/chat-messages'调用聊天框  workflows/run智能体
    api_key = 'app-E5OKzE323dg4s4g8T8lwmG40'  # deepseek
    # api_key = 'app-bBx6yIAQL9LzoBKjDsKOVuxY'  # dawate

    # 请求头
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }

    # 请求数据
    data = {
        "inputs": {},
        "query": query,
        "response_mode": "streaming",  # blocking streaming
        "conversation_id": conversation_id,
        "user": "abc-123",
    }

    # 将数据转换为JSON字符串
    data_json = json.dumps(data)

    # 发送POST请求
    # response = requests.post(url, headers=headers, data=data_json.encode("utf-8"))
    # response.encoding = 'utf-8'

    answer = ''

    # 发送GET请求，并设置stream=True
    with requests.post(url, headers=headers, data=data_json.encode("utf-8"), stream=True) as r:
        # 检查请求是否成功
        r.raise_for_status()

        # 打印每一行文本
        for line in r.iter_lines():
            # 忽略保持连接的空行
            if line:
                # 解码每一行，因为返回的数据可能是字节串
                line = line.decode('utf-8')
                if 'data: ' in line:
                    data = json.loads(line.replace('data: ', ''))
                    if data['event'] == 'message':
                        # print(data['answer'])
                        answer = data['answer']
                        conversation_id = data['conversation_id']
                        yield f"{conversation_id}\t{answer}"
    # return answer, conversation_id


import pymysql
import csv
from datetime import datetime


def db_connet():
    # conn = pymysql.connect(
    #     host='127.0.0.1',  # 连接名称，默认127.0.0.1
    #     user='root',  # 用户名
    #     passwd='123456',  # 密码
    #     port=3306,  # 端口，默认为3306
    #     db='zentao',  # 数据库名称
    #     charset='utf8',  # 字符编码
    # )
    conn = pymysql.connect(**PYMYSQL_CONF)
    print("----数据库连接成功------", conn)
    logging.info("----数据库连接成功------ %s", conn)
    return conn


def data_base_connet(sql_statement):
    # 获取游标
    conn = db_connet()
    cursor = conn.cursor()
    print(cursor)

    # 执行sql语句execute和executemany
    # 定义要执行的SQL语句列表
    try:
        cursor.execute(sql_statement)
        hearders = [description[0] for description in cursor.description]
        results = cursor.fetchall()

        # print(results)

        cursor.close()  # 关闭查询游标
        conn.commit()  # 事务的提交
        conn.close()  # 查询完毕，需要关闭连接，释放计算机资源
        # print('sql执行成功')

        return hearders, results
    except pymysql.MySQLError as e:
        print(f"An error occurred: {e}")
        cursor.close()  # 关闭查询游标
        conn.commit()  # 事务的提交
        conn.close()  # 查询完毕，需要关闭连接，释放计算机资源
        # print('sql执行成功')
        return e, None

def slice_text(text, slice_length):
    slices = []
    slices_new = []
    current_slice = ""
    current_length = 0
    title = ''
    if ':' in text:
        title = text.split('：')[0]
    for char in text:
        current_slice += char
        current_length += 1

        # 当当前切片长度接近1000时，开始寻找分割点
        if current_length >= slice_length:
            # 查找最近的）》号或上一个标点符号
            split_point = re.search(r'》|[^，。！？；：]', current_slice[::-1])
            if split_point:
                # 获取分割点的真实位置
                split_index = len(current_slice) - split_point.start()
                # 添加切片到列表
                slices.append(current_slice[:split_index])
                # 重置当前切片和长度计数器
                current_slice = current_slice[split_index:]
                current_length = len(current_slice)

    # 添加最后一个切片
    if current_slice:
        slices.append(current_slice)
    for i, slice in enumerate(slices):
        if i == 0:
            print(f"切片{i + 1}：长度为：{len(slice)}{slice}\n")
            slices_new.append(slice)
        else:
            print(f"切片{i + 1}：长度为：{len(slice)}{title + slice}\n")
            slices_new.append(title + slice)
    return slices_new


def split_list_into_chunks(lst, chunk_size=5000):
    """
    Splits a list of strings into chunks of a specified size, ensuring that individual strings are not split.

    :param lst: List of strings to be split.
    :param chunk_size: Maximum size of each chunk.
    :return: List of chunks.
    """
    chunks = []
    current_chunk = []

    for item in lst:
        # If adding this item to the current chunk exceeds the chunk size, start a new chunk
        if len(item) > chunk_size:
            print('长度超长了：', len(item))
            slices = slice_text(item, chunk_size)
            for s_i in slices:
                current_chunk.append(s_i)
        if sum(len(x) for x in current_chunk) + len(item) > chunk_size:
            chunks.append(''.join(current_chunk))
            current_chunk = [item]
        else:
            current_chunk.append(item)

    # Add the last chunk if it's not empty
    if current_chunk:
        chunks.append(''.join(current_chunk))

    return chunks

#对剩余团队成员按照工作年限和证书数量排序，优先工作年限
def sorted_rule(item):
    work_years = int(item['工作年限'])
    cert_num = len([i for i in item['证书'] if i != ''])

    return (work_years, cert_num)

#文本基于url的base64编码(+替换成-，/替换成_，=替换成.)
def url_bs64_encode(string):
    bs64_str = str(base64.b64encode(string.encode("utf-8")), "utf-8")
    return  bs64_str.replace('+','-').replace('/','_').replace('=','.')

def team_filter(user_input, task_id, conversation_id):
    '''

    团队内容生成测试：

    :return:
    '''

#     sql_statement = '''
#         SELECT
#     t1.id AS 用户id,
#     t1.name AS 姓名,
#     t1.sex AS 性别,
#     t1.birthday AS 出生日期,
#     t1.idNumber AS 身份证号,
#     t1.company AS 公司,
#     t1.dept AS 部门,
#     t1.workYears AS 工作年限,
#     t2.name AS 证书名称,
#     t2.number AS 证书编号,
#     t2.type AS 证书类型,
#     t2.level AS 证书级别,
#     t2.getDate AS 获取日期,
#     t2.expirationDate AS 失效日期
# FROM
#     ex_team t1
# JOIN
#     ex_teamQualification t2
# ON
#     t1.account = t2.account
#
#         '''
    sql_statement = '''
            SELECT
        t1.id AS 用户id,
        t1.name AS 姓名,
        t1.workYears AS 工作年限,
        t2.name AS 证书名称,
        t2.type AS 证书类型,
        t2.level AS 证书级别
    FROM
        ex_team t1
    LEFT JOIN
        ex_teamQualification t2
    ON
        t1.account = t2.account
    WHERE (t2.expirationDate is null or t2.expirationDate>now())

            '''
    headers, results = data_base_connet(sql_statement)
    if results is not None:
        #对数据做一下处理，将多个证书归纳到一起
        res = {}
        for i in results:
            if i[0] not in res.keys():
                res[i[0]] = {'用户id':i[0],'姓名':i[1],'工作年限':i[2],'证书':[]}
            if i[4]:
                cert_type = i[4]
            else:
                cert_type = '无类别'
            if i[5]:
                cert_level = i[5]
            else:
                cert_level = '无级别'
            if i[3]:
                cert = i[3]
            else:
                cert = ''

            if cert != '':
                res[i[0]]['证书'].append(f"{cert}({cert_type}-{cert_level})")

        #整理成列表
        headers = ['用户id','姓名','工作年限','证书']
        results = []
        for value in res.values():
            results.append([value['用户id'],value['姓名'],value['工作年限'],'、'.join(value['证书'])])

        results_new = [str(i) for i in results]
        split_segments_tem = split_list_into_chunks(results_new, chunk_size=5000)
        split_segments = [str(headers) + str(i) for i in split_segments_tem]
        # query = input('请输入你的问题:')
        # query='找出中级以上的用户有哪些'
        local_conversation_id = ''
        # while True:
        # user_input = input('用户输入要求：')
        # user_input='''
        # 要求：1、项目固定服务技术团队3人（含）以上，团队少于3人的得0分，3人以上得2分；2、项目经理具备CISP证书或信息系统项目集成工程师，均不具备的得0分，具备其中1证的得3分，都具备的得5分；3、服务工程师均具备CCNP或HCNP或H3CNE证书，有1人不具备的得0分，均具备1-2证的得3分，均具备2证以上的得5分；4、项目经理具有3年以上信息安全工作经验，服务工程师均具有1年以上的信息安全项目运维实施工作经验，不满足条件的得0分，满足1项条件的得2分，均满足条件的得3分。
        #
        # '''
        # if '再见' in user_input:
        #     data_answ, conversation_id = dify_chat2('要求：' + str((user_input)), conversation_id=conversation_id)
        #     print('再见：', data_answ)
        # else:
        answer_merge = []
        # prompt_1 = '''
        # 提示词：帮我进行项目经理以及团队成员推荐，只需一个项目经理，团队成员推荐中不需要包含项目经理，如果没有团队人数要求为0即可，并对团队进行评分，并且根据证书级别对用户进行归类。
        # 并以json格式输出：{"推荐项目经理为": {"用户id","xxx","姓名"："xxx"}，
        #                 "推荐团队成员为": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}],
        #                 "团队人数": n,
        #                 "团队评分为": "xxx分",
        #                 "中级证书成员有": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}],
        #                 "高级证书成员有": [{"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"},
        #                                 {"用户id"："xxx"，"姓名"："xxx","拥有证书"："xxx"}]
        #                                 }
        # '''
        prompt_1 = '''
                        提示词：帮我进行项目经理以及团队成员推荐，如人数不符合要求则忽略人数要求，项目团队中需要包含所有符合条件的人员(如果项目经理也符合条件，则也加入到项目团队中)，不限人数，只需一个项目经理，以下为示例：
                        ###输入###
                        团队专业技术人员不少于50人，同时包含至少5 位持有软件类中级及以上证书人员或具备同类项目 业绩（提供参与业绩相关证明，如合同人员、验收 证书项目成员等），具有完善合理的团队稳定的保障 措施，得15分；
                        ###输出###
                        并以json格式输出：```json
                                        {"推荐项目经理": {"用户id","xxx","姓名"："xxx"}，
                                        "推荐团队成员": [{"用户id"："xxx"，"姓名"："xxx"},
                                                        {"用户id"："xxx"，"姓名"："xxx"}],
                                        "要求的团队人数": 50,
                                        "团队要求": "软件类中级及以上证书人员或具备同类项目业绩"}
                                        ```
                        ###输入###
                        1）拟委派的项目经理具有 CISP证书的加2分，具有 CISSP加3分，可以累加； 2）拟委派的项目团队成员具 有1个及以上软件设计师， 得3分；每多1个软件设计 师加1分，最多加2分。 3）拟委派的项目团队成员具 有1个及以上CISP，得3分； 每多1个CISP加1分，最多 加2分。 
                        ###输出###
                        并以json格式输出：
                                        ```json
                                        {"推荐项目经理": {"用户id","xxx","姓名"："xxx"}，
                                        "推荐团队成员": [{"用户id"："xxx"，"姓名"："xxx"},
                                                        {"用户id"："xxx"，"姓名"："xxx"}],
                                        "要求的团队人数": 0,
                                        "团队要求": "软件设计师、CISP"}
                                        ```
                        思考过程精简一些
                        '''
        for index, cont_i in enumerate(split_segments):
            print('表格切分后的内容：', len(str(cont_i)), cont_i)

            stream_content = dify_chat2('数据为：' + str(cont_i) + str((user_input)) + str(prompt_1),
                                                    conversation_id=local_conversation_id)
            data_answ = ''
            try:
                while True:
                    gen_text = next(stream_content)
                    gen_text_split = gen_text.split('\t')
                    local_conversation_id = gen_text_split[0]
                    answer = '\t'.join(gen_text_split[1:])
                    data_answ += answer
                    # yield answer
                    yield f'{task_id}\t{conversation_id}\t{answer}'
                    print(answer, end='')

            except StopIteration as e:
                # conversation_id = e.value
                pass

            # data_answ, conversation_id = dify_chat2('数据为：' + str(cont_i) + str((user_input)) + str(prompt_1),
            #                                         conversation_id=conversation_id)
            # file_.writelines(data_answ + '\n')
            print(f'\n------结果{index}：--------\n', data_answ)
            data_answ = data_answ.split('</think>')[-1]
            answer_merge.append(data_answ)

        #返回文件生成中
        yield f'{task_id}\t{conversation_id}\t\n团队管理文件生成中...\n'

        print('-------模型输出结果：-------', answer_merge)
        if len(split_segments) > 1:
            # data_answ, conversation_id = dify_chat2('将结果进行合并,并以json格式输出,原始的json格式不要变。' + str(answer_merge),
            #                                     conversation_id=conversation_id)
            stream_content = dify_chat2('将结果进行合并,并以json格式输出,原始的json格式不要变。' + str(answer_merge),
                                        conversation_id=local_conversation_id)
            data_answ = ''
            try:
                while True:
                    gen_text = next(stream_content)
                    gen_text_split = gen_text.split('\t')
                    local_conversation_id = gen_text_split[0]
                    data_answ += '\t'.join(gen_text_split[1:])
                    # sys.stdout.write(f"\r {[data_answ]}")
                    # sys.stdout.flush()

            except StopIteration as e:
                # conversation_id = e.value
                pass
            print('-----结果合并后的结果------', data_answ)

        # 获取返回的json
        pattern = r"```json(.*?)```"
        matches = re.findall(pattern, data_answ, re.DOTALL)
        if len(matches) != 0:
            llm_data = json.loads(matches[-1])
            # print('\n')
            print(llm_data)
        else:
            return 0, []

        #整理id
        header_id = llm_data['推荐项目经理']['用户id']
        team_ids = [i['用户id'] for i in llm_data['推荐团队成员']]
        if header_id not in team_ids:
            team_ids = [header_id] + team_ids

        # for i in team_ids:
        #     print(res[i])
        print('================================')

        #筛选剩余人员，并按照工作年限和证书数量排序
        other_person = []
        for _id in set(res.keys())-set(team_ids):
            other_person.append(res[_id])

        # 根据相似度排序
        other_person = sorted(other_person, key=lambda x: sorted_rule(x), reverse=True)

        print(len(team_ids))

        chazhi = llm_data['要求的团队人数'] - len(team_ids)
        if chazhi > 0:
            for i in other_person[:chazhi]:
                team_ids.append(i['用户id'])
                print(res[i['用户id']])
                # extra_person += f"{i['姓名']}(工作年限：{i['工作年限']})；"

        print(len(team_ids))
        if len(team_ids) == 0:
            yield f'{task_id}\t{conversation_id}\t\n未找到相关团队'
            return

        #总结的话
        refer_person = [i['姓名'] for i in llm_data['推荐团队成员']]
        extra = {'cnt':len(refer_person), 'person': '、'.join(refer_person), '团队要求': llm_data['团队要求']}

        #生成文件
        filename, save_path = get_team('team', team_ids, header_id, extra)

        #返回下载链接
        download_url = f"/api/bid/get_file?path={url_bs64_encode(save_path)}"
        yield f'{task_id}\t{conversation_id}\t\n下载链接：<a href="{download_url}">{filename}</a>'

        return header_id, team_ids

if __name__ == "__main__":
    # main()

    # step1用户意图识别
    # intention_recognition()

    # step2 意图为：团队数据筛选  根据招标要求进行团队数据筛选及其团队推荐
    st = time.time()
    s = team_filter('1.团队专业技术人员不少于 10 人，同时包含至少 5 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），具有完善合理的团队稳定的保障措施，得 15 分；\n2.团队专业技术人员不少于 5 人，同时包含至少3 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），团队稳定的保障措施基本合理，得 10 分；\n3.团队专业技术人员不少于 3 人，同时包含至少1 位持有软件类中级及以上证书人员或具备同类项目业绩（提供参与业绩相关证明，如合同人员、验收证书项目成员等），有团队稳定的保障措施，得 5 分；\n4.其他情况或没有内容不得分。\n需提供人员证书及在职证明材料（提供在本单位投标截止日期前半年内任意连续 3 个月的社保证明或在本单位的在职劳动合同）。',"","")
    try:
        while True:
            gen_text = next(s)

    except StopIteration as e:
        # conversation_id = e.value
        pass
    print(time.time()-st)
    # query='你是谁'
    # data_answ,conversation_id= dify_chat_streaming(str(query))
    # print(data_answ,conversation_id)